package org.hackystat.devcathlon.engine.user;

import java.io.Serializable;
import java.util.HashSet;
import java.util.Set;
import org.hackystat.devcathlon.engine.profile.Profile;

/**
 * A devcathlon user, who must also be a registered Hackystat user.
 * This class stores user profile information.
 * The email and password must be legal credentials for the sensorbase associated with this
 * Devcathlon instance.   
 * @author Philip Johnson
 */
public class User implements Serializable, Comparable<User> {
  /** Support serialization. */
  private static final long serialVersionUID = 1L;
  /** Primary key reference id. */
  private Long id;
  /** The username of this user and is also a unique identifier.*/
  private String username;
  /** The user Profile. */
  private Profile profile;
  /** The first name of this user. */
  private String firstName;
  /** The last name of this user. */
  private String lastName;
  /** The email for this user, also their Hackystat account. */
  private String email;
  /** The hackystat password for this user. */
  private String password;
  /** The associated teams for this user. */
  private Set teams = new HashSet();

  /**
   * Default User constructor.
   */
  public User() {
    // empty constructor
  }
  
  /**
   * Creates a new user. Typically done by the UserManager.
   * @param username The username.
   * @param firstName The first name. 
   * @param lastName The last name. 
   * @param email The email. 
   * @param password The password. 
   */
  User(String username, String firstName, String lastName, String email, String password) {
    this.username = username;
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.password = password;
  }
  
  /**
   * Creates a new user. Typically done by the UserManager.  
   * @param firstName The first name. 
   * @param lastName The last name. 
   * @param email The email. 
   * @param password The password. 
   */
  User(String firstName, String lastName, String email, String password) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.email = email;
    this.password = password;
  }
  
  /**
   * Set the id of this user.
   * @param id the id to set
   */
  public void setId(Long id) {
    this.id = id;
  }

  /**
   * Return the id of this user.
   * @return the id
   */
  public Long getId() {
    return id;
  }

  /**
   * Set the username of this user.
   * @param username The username of this user.
   */
  public void setUsername(String username) {
    this.username = username;
  }
  
  /**
   * Return the username of this user.
   * @return the username
   */
  public String getUsername() {
    return username;
  }
  
  /**
   * Set the profile for this user.
   * @param profile the profile to set
   */
  public void setProfile(Profile profile) {
    this.profile = profile;
  }

  /**
   * Return the profile for this user.
   * @return the profile
   */
  public Profile getProfile() {
    return profile;
  }
  
  /**
   * Set the first name of this user.
   * @param firstName The first name
   */
  public void setFirstName(String firstName) {
    this.firstName = firstName;
  }
  
  /**
   * Return the first name of this user. 
   * @return The first name. 
   */
  public String getFirstName() {
    return this.firstName;
  }

  /**
   * Set the last name of this user.
   * @param lastName The last name
   */
  public void setLastName(String lastName) {
    this.lastName = lastName;
  }
  
  /**
   * Return the last name of this user. 
   * @return The last name. 
   */
  public String getLastName() {
    return this.lastName;
  }

  /**
   * Set the email for this user.
   * @param email The email
   */
  public void setEmail(String email) {
    this.email = email;
  }
  
  /**
   * Return the email (Hackystat account) for this user. 
   * @return The email.
   */
  public String getEmail() {
    return this.email;
  }
  
  /**
   * Set the password for this user.
   * @param password The password
   */
  public void setPassword(String password) {
    this.password = password;
  }

  /**
   * Return the Hackystat password of this user. 
   * @return The password.
   */
  public String getPassword() {
    return this.password;
  }

  /**
   * Return all teams associated to this user.
   * @return The teams.
   */
  public Set getTeams() {
    return teams;
  }

  /**
   * Set the set of teams for this user.
   * @param teams The teams set.
   */
  public void setTeams(Set teams) {
    this.teams = teams;
  }

  
  /**
   * Updates the user's credentials.  Required if user was invited
   * before he joined Devcathlon system.
   * @param email The user's email.
   * @param password The user's password.
   */
  public void updateCredentials(String email, String password) {
    this.email = email;
    this.password = password;
  }

  /**
   * Sets the class to have natural sorting order by last name.
   * @param user The user to compare.
   * @return A negative if less than, positive if greater.
   */
  public int compareTo(User user) {
    return this.lastName.compareTo(user.getLastName());
  }  
  
  /** 
   * Compares any object and returns true if equals.
   * @param obj The object to compare
   * @return The boolean if object is equal.
   */
  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (!(obj instanceof User)) {
      return false;
    }
    if (!(this.email.equals(((User)obj).getEmail()))) {
      return false;
    }
    if (!(this.firstName.equals(((User)obj).getFirstName()))) {
      return false;
    }
    if (!(this.lastName.equals(((User)obj).getLastName()))) {
      return false;
    }
    if (!(this.password.equals(((User)obj).getPassword()))) {
      return false;
    }
    return true;
  }
  
  /**
   *  Generic override, likely won't be used.  Needed because equals() was override.
   *  @return The hash code value.
   */
  public int hashCode() {
    int hash = 1;
    hash = hash * 31 + email.hashCode();
    hash = hash * 31
                + (username == null ? 0 : username.hashCode());
    return hash;
//    assert false : "hashCode not designed";
//    return 42; // any arbitrary constant will do
  }
}
